#include <SPI.h> //Library for interaction of the microcontroller with various peripheral devices via the SPI protocol

#include <Adafruit_GFX.h> // library for working with LED matrix
#include <Max72xxPanel.h> // library for working with LED matrix
#include <iarduino_RTC.h> //The library allows you to read and record the time of RTC modules based on chips: DS1302, DS1307, DS3231
iarduino_RTC time(RTC_DS1307);

#include <EEPROM.h> // Library for working with non-volatile Arduino memory
#include <TimerOne.h> // Library for working with the built-in Arduino timer

#include <SimpleRotary.h> // Library for working with the encoder
SimpleRotary rotary(7, 8, 4);

char status;

extern volatile unsigned long timer0_millis;
uint32_t OneDay_timer, startTime, currentMillis;


char Corr_time;

int gg1, mm1, dd1, gg2, mm2, dd2, hr1, hr2;

long New_Hours = 0;
long New_minutes = 0;
long New_seconds = 0;
long Corr_time_long = 0;
long JD1 = 0;
long JD2 = 0;

String c_par;
#define lightPin A3 // assign pin A3 to connect to the light sensor
int ligth_Intensity;
int ligth_Intensity2;

int s_mode, a_mode, LeapYear;

#define movPin 5 // assign pin 5 to connect to the motion sensor

int pinCS = 10; // assign pin 10 to connect the CS LED matrix pin

Max72xxPanel matrix = Max72xxPanel(10, 1, 4); // initialize the LED matrix

// a constant containing an image of a smiley face/////////
const byte data[8] = {
  0b00111100,
  0b01000010,
  0b10100101,
  0b10000001,
  0b10100101,
  0b10011001,
  0b01000010,
  0b00111100
};
////////////////////////////////////////////////////////
String tape; // text to display a running line
int wait = 20; // time in milliseconds between letter movements

unsigned long pr_tm = 0;
unsigned long lg_tm = 0;

int spacer = 1; // distance between letters
int width = 5 + spacer; // font size

void setup(void) {
  OneDay_timer = 0;
  s_mode = 0; // a variable that defines the device mode "time display" or "date and time setting mode"
  a_mode = 0; // a variable that determines the transfer of the device to the time setting mode
  int Num_day;

  Serial.begin(9600);
  
  time.begin();
  
  pinMode(movPin, INPUT); // setting the mode for the motion sensor pin
  pinMode(lightPin, INPUT); // setting the mode for the light sensor pin

  //time.settime(0,06,15,28,4,19,0);  // 0 sec, 51 min, 21 h, October 27, 2015, Tuesday - when the sketch is first filled in, initialize the real-time clock, then comment out this line again and re-edit the sketch
  
  matrix.setRotation(matrix.getRotation() + 3); //1 - 90 2 - 180 3 - 270 degrees - set the orientation of the LED matrix



//////////// when the device is turned on, we briefly display a smiley face////////
  for ( int y = 0; y < 8; y++ ) {
    for ( int x = 0; x < 8; x++ ) {
      // we light the x-th pixel in the y-th line
      matrix.drawPixel(x + 12, y, data[y] & (1 << x));
    }
    matrix.write(); // output of all pixels to the matrix
    delay(100);
  }
   delay(3000);
/////////////////////////////////////////////////////////////////////////////
  
  ligth_Intensity = 0; // we set the initial values of ambient illumination
  ligth_Intensity2 = 0;


  ///////////////////////////////////////////////////////////////////////////
  time.gettime("d-m-Y, H:i:s, D");

  Corr_time = EEPROM.read(0); // we read the time correction variable from the non-volatile memory
  if (Corr_time > 60 || Corr_time < -60) Corr_time = 0; // if the time correction is more/less than a minute, then the device is turned on for the first time, then set the value of the variable 0

  dd1 = EEPROM.read(1); // we read from non-volatile memory the number of the month when the clock was last adjusted
  if (dd1 > 31 || dd1 < 0) {
    dd1 = time.day;
    EEPROM.write(1, dd1);
  }

  mm1 = EEPROM.read(2); // we read from non-volatile memory the month when the clock was last adjusted
  if (mm1 > 12 || mm1 < 0) {
    mm1 = time.month;
    EEPROM.write(2, mm1);
  }

  gg1 = EEPROM.read(3); // we read from non-volatile memory the year when the clock was last adjusted
  if (gg1 > 73 || gg1 < 0) {
    gg1 = time.year;
    EEPROM.write(3, gg1);
  }

  hr1 = EEPROM.read(4); // we read from the non-volatile memory the hour when the clock was last adjusted
  if (hr1 > 24 || hr1 < 0) {
    hr1 = time.Hours;
    EEPROM.write(4, hr1);
  }

  dd2 = time.day; // assign the current time and date to the intermediate variables
  mm2 = time.month;
  gg2 = time.year;
  hr2 = time.Hours;

// we determine the Julian date for the moment of the last adjustment of the clock 
  if (mm1 < 3) {
    JD1 = int((gg1 - 1) * 365.25) + int((mm1 + 12) * 30.6 + (float)0.7) + dd1;
  }
  else {
    JD1 = int(gg1 * 365.25) + int(mm1 * 30.6 + (float)0.7) + dd1;
  }

// we determine the Julian date for the current system time in the clock (our device)
  if (mm2 < 3) {
    JD2 = int((gg2 - 1) * 365.25) + int((mm2 + 12) * 30.6 + (float)0.7) + dd2;
  }
  else {
    JD2 = int(gg2 * 365.25) + int(mm2 * 30.6 + (float)0.7) + dd2;
  }
// we determine the number of hours that have passed since the last time correction
  if (hr2 >= hr1) {
    Corr_time_long = round(((long)24 * (JD2 - JD1) + hr2 - hr1) * ((float)Corr_time / 24));
  }
  else {
    Corr_time_long = round(((long)24 * (JD2 - JD1 - 1) + (24 + hr2 - hr1)) * ((float)Corr_time / 24));
  }

  //we translate the current system time into seconds and add an adjustment taking into account the accuracy of the stroke
  long Total_new_sec = (long)time.Hours * 3600 + (long)time.minutes * 60 + time.seconds + Corr_time_long;
  
  if (Total_new_sec >= 0) {
    Num_day = int((long)Total_new_sec / 86400);
  }
  else {
    Num_day = -1 + int((long)Total_new_sec / 86400);
  }

  if (Total_new_sec > 0) {

    for (int nd = 0; nd < Num_day; nd++) {

      if (time.month == 2) {
        LeapYear = 0;  //definition of a leap year
        if ( (((2000 + int(time.year)) % 4) == 0) & (((2000 + int(time.year)) % 100) != 0)  || (((2000 + int(time.year)) % 400) == 0) ) {
          LeapYear = 1;
        }
        else {
          LeapYear = 0;
        }
      }

      if ((time.day == 31) & (time.month == 1 || time.month == 3 || time.month == 5 || time.month == 7 || time.month == 8 || time.month == 10 || time.month == 12))
      { time.day = 1;
        if (time.month < 12) {
          time.month++;
          time.weekday++;
        }
        else {
          time.month = 1;
          time.weekday++;
          time.year++;
        }
      }
      else if ((time.day == 30) & (time.month == 4 || time.month == 6 || time.month == 9 || time.month == 11))
      { time.day = 1;
        time.month++;
        time.weekday++;
      }
      else if ((time.day == 29) & (time.month == 2) & (LeapYear == 1) )
      { time.day = 1;
        time.month++;
        time.weekday++;
      }
      else if ((time.day == 28) & (time.month == 2) & (LeapYear == 0) )
      { time.day = 1;
        time.month++;
        time.weekday++;
      }
      else
      {
        time.day ++;
        time.weekday++;
      }
    }
  }

  if (Total_new_sec < 0) {

    Num_day = abs(Num_day);

    for (int nd = 0; nd < Num_day; nd++) {

      if (time.day == 1)
      {
        if ((time.month == 1 || time.month == 3 || time.month == 5 || time.month == 7 || time.month == 8 || time.month == 10 || time.month == 12))
        { time.day = 31;
          time.month--;
          time.weekday--;
          if (time.month = 1) {
            time.year--;
          }
        }
        else if ((time.month == 4 || time.month == 6 || time.month == 9 || time.month == 11))
        { time.day = 30;
          time.month--;
          time.weekday--;
        }
        else if ((time.month == 2) & (LeapYear == 0))
        { time.day = 29;
          time.month--;
          time.weekday--;
        }
        else if ((time.month == 2) & (LeapYear == 0) )
        { time.day = 28;
          time.month--;
          time.weekday--;
        }
      }
      else
      {
        time.day --;
        time.weekday--;
      }
    }
  }


  ////////////////////////date correction///////////////////////////////////////////////

  Corr_time_long = Corr_time_long -  int((long)Corr_time_long / 86400) * 86400;

  long new_sec = (long)time.Hours * 3600 + (long)time.minutes * 60 + time.seconds + Corr_time_long;

  if (new_sec < 0) {
    New_Hours = 23;
    New_minutes = 59;
    New_seconds = 60 + time.minutes + new_sec;
  }
  if (new_sec > 0) {
    New_Hours = int ((long)new_sec / 3600);
    New_minutes = int ((long)(new_sec - (long)New_Hours * 3600) / 60);
    New_seconds = new_sec - (long)New_Hours * 3600 - (long)New_minutes * 60;
  }

  if (New_Hours > 23) New_Hours = New_Hours - 24;

  time.Hours = New_Hours;
  time.minutes = New_minutes;
  time.seconds = New_seconds;
  /////////////////////////////////defining a new date and day of the week//////////////////


  /////////////////////////////////defining a new date and day of the week//////////////////

  time.settime(time.seconds, time.minutes, time.Hours, time.day, time.month, time.year, time.weekday);

  time.gettime("d-m-Y, H:i:s, D");

  dd2 = time.day;
  mm2 = time.month;
  gg2 = time.year;
  hr2 = time.Hours;

// we record the date and time of the clock correction
  EEPROM.write(1, dd2);
  EEPROM.write(2, mm2);
  EEPROM.write(3, gg2);
  EEPROM.write(4, hr2);

  ////////////////////////////////////////////////////////////////////////////

}

int dots = 0;
long dotTime = 0;
int h, m, s;
int Num_day;
// =======================================================================


void loop(void) {

  //time correction////////////////////////////////////

  New_Hours = 0;
  New_minutes = 0;
  New_seconds = 0;

  if (millis() - OneDay_timer >= 86400000) {   // time correction timer - once a day
    OneDay_timer = millis();              // resetting the timer

    time.gettime("d-m-Y, H:i:s, D");

    long new_sec = (long)time.Hours * 3600 + (long)time.minutes * 60 + time.seconds + Corr_time;

    ////////////////////////date correction///////////////////////////////////////////////
    long Total_new_sec = (long)time.Hours * 3600 + (long)time.minutes * 60 + time.seconds + Corr_time;
    if (Total_new_sec >= 0) {
      Num_day = int((long)Total_new_sec / 86400);
    }
    else {
      Num_day = -1 + int((long)Total_new_sec / 86400);
    }

    if (Total_new_sec > 0) {

      for (int nd = 0; nd < Num_day; nd++) {

        if (time.month == 2) {
          LeapYear = 0;  //definition of a leap year
          if ( (((2000 + int(time.year)) % 4) == 0) & (((2000 + int(time.year)) % 100) != 0)  || (((2000 + int(time.year)) % 400) == 0) ) {
            LeapYear = 1;
          }
          else {
            LeapYear = 0;
          }
        }

        if ((time.day == 31) & (time.month == 1 || time.month == 3 || time.month == 5 || time.month == 7 || time.month == 8 || time.month == 10 || time.month == 12))
        { time.day = 1;
          if (time.month < 12) {
            time.month++;
            time.weekday++;
          }
          else {
            time.month = 1;
            time.weekday++;
            time.year++;
          }
        }
        else if ((time.day == 30) & (time.month == 4 || time.month == 6 || time.month == 9 || time.month == 11))
        { time.day = 1;
          time.month++;
          time.weekday++;
        }
        else if ((time.day == 29) & (time.month == 2) & (LeapYear == 1) )
        { time.day = 1;
          time.month++;
          time.weekday++;
        }
        else if ((time.day == 28) & (time.month == 2) & (LeapYear == 0) )
        { time.day = 1;
          time.month++;
          time.weekday++;
        }
        else
        {
          time.day ++;
          time.weekday++;
        }
      }
    }

    if (Total_new_sec < 0) {

      Num_day = abs(Num_day);

      for (int nd = 0; nd < Num_day; nd++) {

        if (time.day == 1)
        {
          if ((time.month == 1 || time.month == 3 || time.month == 5 || time.month == 7 || time.month == 8 || time.month == 10 || time.month == 12))
          { time.day = 31;
            time.month--;
            time.weekday--;
            if (time.month = 1) {
              time.year--;
            }
          }
          else if ((time.month == 4 || time.month == 6 || time.month == 9 || time.month == 11))
          { time.day = 30;
            time.month--;
            time.weekday--;
          }
          else if ((time.month == 2) & (LeapYear == 0))
          { time.day = 29;
            time.month--;
            time.weekday--;
          }
          else if ((time.month == 2) & (LeapYear == 0) )
          { time.day = 28;
            time.month--;
            time.weekday--;
          }
        }
        else
        {
          time.day --;
          time.weekday--;
        }
      }
    }


    ////////////////////////date correction///////////////////////////////////////////////

    if (new_sec < 0) {
      New_Hours = 23;
      New_minutes = 59;
      New_seconds = 60 + time.minutes + new_sec;
    }
    if (new_sec > 0) {
      New_Hours = int ((long)new_sec / 3600);
      New_minutes = int ((long)(new_sec - (long)New_Hours * 3600) / 60);
      New_seconds = new_sec - (long)New_Hours * 3600 - (long)New_minutes * 60;
    }
    if (New_Hours > 23) New_Hours = New_Hours - 24;

    time.Hours = New_Hours;
    time.minutes = New_minutes;
    time.seconds = New_seconds;

    time.settime(time.seconds, time.minutes, time.Hours, time.day, time.month, time.year, time.weekday);


    time.gettime("d-m-Y, H:i:s, D");

    dd2 = time.day;
    mm2 = time.month;
    gg2 = time.year;
    hr2 = time.Hours;

    EEPROM.write(1, dd2);
    EEPROM.write(2, mm2);
    EEPROM.write(3, gg2);
    EEPROM.write(4, hr2);

  }

  //time correction//////////////////////////////////


  int Zahod_time[12] = {8, 7, 7, 6, 6, 5, 5, 6, 6, 7, 7, 8}; //the array contains the hour of the end of the sleep mode of the hours for each year of the month
  int val_mP;
  String mm, wd;

  light_set();

  time.gettime("d-m-Y, H:i:s, D");
  //Data
  String  hr = String( time.Hours);
  if (time.Hours < 10) hr = "0" + hr;
  String  mn = String( time.minutes);
  if (time.minutes < 10) mn = "0" + mn;
  String  dd = String( time.day);
  if (time.day < 10) hr = "0" + dd;
  String  yy = String( time.year);

  //Data
  if (time.month == 1) mm = "Jan";
  else if (time.month == 2) mm = "Feb";
  else if (time.month == 3) mm = "March";
  else if (time.month == 4) mm = "Apr";
  else if (time.month == 5) mm = "May";
  else if (time.month == 6) mm = "Jun";
  else if (time.month == 7) mm = "Jul";
  else if (time.month == 8) mm = "Aug";
  else if (time.month == 9) mm = "Sep";
  else if (time.month == 10) mm = "Oct";
  else if (time.month == 11) mm = "Nov";
  else if (time.month == 12) mm = "Dec";

       if (time.weekday == 0) wd = "sun";
  else if (time.weekday == 1) wd = "mon";
  else if (time.weekday == 2) wd = "tue";
  else if (time.weekday == 3) wd = "wed";
  else if (time.weekday == 4) wd = "thu";
  else if (time.weekday == 5) wd = "fri";
  else if (time.weekday == 6) wd = "sat";


  int rDir = rotary.rotate();
  int rBtn = rotary.push();
 
  // when you click on the encoder, you switch to the time settings
  if ( rBtn == 1 )
  {

    if (s_mode == 0) {
      s_mode = 1;

      set_param();
    }
  }


  /////////////////////////
  //when turning the encoder to the right - show the date 
  if ( rDir == 1 ) {

    //------------temperature


    //Data
    if (time.Hours < Zahod_time[time.month - 1]) {
      startTime = millis();
      while ((currentMillis = millis()) - startTime < 3000ul) {//starting the timer
        DisplayTime();
        if (millis() - dotTime > 500) {
          dotTime = millis();
          dots = !dots;
        }
      }
    }
    tape = (dd + "/" + mm + "/20" + yy + "/" + wd);
    print_info();
  }

  //when turning the encoder to the left - show the date
  if ( rDir == 2 ) {

    //Data
    if (time.Hours < Zahod_time[time.month - 1]) {
      startTime = millis();
      while ((currentMillis = millis()) - startTime < 3000ul) {//starting the timer
        DisplayTime();
        if (millis() - dotTime > 500) {
          dotTime = millis();
          dots = !dots;
        }
      }
    }
    tape = (dd + "/" + mm + "/20" + yy + "/" + wd);
    print_info();

  }
  ////////////////////////////////


  //time.gettime("d-m-Y, H:i:s, D");
  if (time.Hours < Zahod_time[time.month - 1]) { ///////////////////night illumination

    val_mP = digitalRead(movPin);

    if (val_mP) {

      if (millis() - pr_tm >= 60000) {
        pr_tm = millis();

        startTime = millis();
        while ((currentMillis = millis()) - startTime < 2000ul) {//starting the timer
          DisplayTime();
          if (millis() - dotTime > 500) {
            dotTime = millis();
            dots = !dots;
          }
        }

        //Data
  if (time.month == 1) mm = "Jan";
  else if (time.month == 2) mm = "Feb";
  else if (time.month == 3) mm = "March";
  else if (time.month == 4) mm = "Apr";
  else if (time.month == 5) mm = "May";
  else if (time.month == 6) mm = "June";
  else if (time.month == 7) mm = "July";
  else if (time.month == 8) mm = "Aug";
  else if (time.month == 9) mm = "Sep";
  else if (time.month == 10) mm = "Oct";
  else if (time.month == 11) mm = "Nov";
  else if (time.month == 12) mm = "Dec";

       if (time.weekday == 0) wd = "sun";
  else if (time.weekday == 1) wd = "mon";
  else if (time.weekday == 2) wd = "tue";
  else if (time.weekday == 3) wd = "wed";
  else if (time.weekday == 4) wd = "thu";
  else if (time.weekday == 5) wd = "fri";
  else if (time.weekday == 6) wd = "sat";


        tape = (dd + "/" + mm + "/20" + yy + "/" + wd);
        print_info();

        startTime = millis();
        while ((currentMillis = millis()) - startTime < 5000ul) {//starting the timer
          DisplayTime();
          if (millis() - dotTime > 500) {
            dotTime = millis();
            dots = !dots;
          }
        }
        matrix.fillScreen(LOW);
        matrix.write();
      }
    }
  }

  if ((time.Hours == 0) & (time.minutes == 0) & (time.seconds < 3)) {// at midnight, the clock switches to sleep mode and wishes good night
    for (int i = 0; i < 3; i++) {
      tape = ("Good night!");
      print_info();
    }
  }


  if ((time.Hours == Zahod_time[time.month - 1]) & (time.minutes == 0) & (time.seconds < 3)) {// at the end of sleep mode, the clock wishes good morning
    for (int i = 0; i < 3; i++) {
      tape = ("Good morning!");
      print_info();
    }
  }



  if ( time.Hours >= Zahod_time[time.month - 1]) {
    DisplayTime();
    if (millis() - dotTime > 500) {
      dotTime = millis();
      dots = !dots;
    }

    val_mP = digitalRead(movPin);//////////////////////     daytime illumination

    if (val_mP) {

      if (millis() - pr_tm >= 60000) {
        pr_tm = millis();


        time.gettime("d-m-Y, H:i:s, D");
        //Data
        String  hr = String( time.Hours);
        if (time.Hours < 10) hr = "0" + hr;
        String  mn = String( time.minutes);
        if (time.minutes < 10) mn = "0" + mn;
        String  dd = String( time.day);
        if (time.day < 10) hr = "0" + dd;
        String  yy = String( time.year);
        //Data
  if (time.month == 1) mm = "Jan";
  else if (time.month == 2) mm = "Feb";
  else if (time.month == 3) mm = "March";
  else if (time.month == 4) mm = "Apr";
  else if (time.month == 5) mm = "May";
  else if (time.month == 6) mm = "June";
  else if (time.month == 7) mm = "July";
  else if (time.month == 8) mm = "Aug";
  else if (time.month == 9) mm = "Sep";
  else if (time.month == 10) mm = "Oct";
  else if (time.month == 11) mm = "Nov";
  else if (time.month == 12) mm = "Dec";

       if (time.weekday == 0) wd = "sun";
  else if (time.weekday == 1) wd = "mon";
  else if (time.weekday == 2) wd = "tue";
  else if (time.weekday == 3) wd = "wed";
  else if (time.weekday == 4) wd = "thu";
  else if (time.weekday == 5) wd = "fri";
  else if (time.weekday == 6) wd = "sat";


        tape = (dd + "/" + mm + "/20" + yy + "/" + wd);
        print_info();

      }
    }
  }
  else
  {
    matrix.fillScreen(LOW);
    matrix.write();
  }
}

// =======================================================================
void DisplayTime() {
  light_set();
  updateTime();
  matrix.fillScreen(LOW);
  int y = (matrix.height() - 8) / 2; // Centering the text Vertically

  if (s & 1) {
    matrix.drawChar(14, y, (String(":"))[0], HIGH, LOW, 1); //every even second we print a colon in the center (to make it blink)
  }
  else {
    matrix.drawChar(14, y, (String(" "))[0], HIGH, LOW, 1);
  }

  String hour1 = String (h / 10);
  String hour2 = String (h % 10);
  String min1 = String (m / 10);
  String min2 = String (m % 10);
  String sec1 = String (s / 10);
  String sec2 = String (s % 10);
  int xh = 2;
  int xm = 19;
  //    int xs = 28; //seconds

  matrix.drawChar(xh, y, hour1[0], HIGH, LOW, 1);
  matrix.drawChar(xh + 6, y, hour2[0], HIGH, LOW, 1);
  matrix.drawChar(xm, y, min1[0], HIGH, LOW, 1);
  matrix.drawChar(xm + 6, y, min2[0], HIGH, LOW, 1);

  light_set ();
  matrix.write(); // Output to the display
}

void updateTime()
{
  time.gettime("d-m-Y, H:i:s, D");


  if ((time.Hours == 13) & (time.minutes == 13)) {
    time.gettime("d-m-Y, H:i:s, D");
    h = time.hours;
    m = time.minutes + 1;
  }
  else if ((time.Hours == 13) & (time.minutes != 13)) {
    time.gettime("d-m-Y, H:i:s, D");
    h = time.hours;
    m = time.minutes;
  }
  else if ((time.Hours != 13) & (time.minutes == 13)) {
    time.gettime("d-m-Y, H:i:s, D");
    h = time.Hours;
    m = time.minutes + 1;
  }
  else if ((time.Hours != 13) & (time.minutes != 13)) {
    time.gettime("d-m-Y, H:i:s, D");
    h = time.Hours;
    m = time.minutes;
  }

  s = time.seconds;
}

void print_info ()
{

  for ( int i = 0 ; i < width * tape.length() + matrix.width() - 1 - spacer; i++ ) {
    matrix.fillScreen(LOW);

    int letter = i / width;
    int x = (matrix.width() - 1) - i % width;
    int y = (matrix.height() - 8) / 2; // center the text vertically

    while ( x + width - spacer >= 0 && letter >= 0 ) {
      if ( letter < tape.length() ) {
        matrix.drawChar(x, y, tape[letter], HIGH, LOW, 1);
      }
      letter--;
      x -= width;

      light_set();
    }

    matrix.write();
    delay(wait);
  }
  tape = " ";
}


void change_param(String c_par)
{
  matrix.fillScreen(LOW);
  int y = (matrix.height() - 8) / 2; // Centering the text Vertically
  for ( int i = 0 ; i < c_par.length(); i++ ) {
    matrix.drawChar(i * (width), y, c_par[i], HIGH, LOW, 1);
  }

  light_set ();
  matrix.write(); // Output to the display
}

unsigned int f_div(unsigned int x, unsigned int y) {
  unsigned int result;
  result = (x - (x % y)) / y;
  return result;
}

void set_param()
{

  byte Set_Hours = time.Hours;
  byte Set_minutes = time.minutes;
  byte Set_day = time.day;
  byte Set_month = time.month;
  byte Set_year = time.year;
  byte ned;

  c_par = ("Y:") + String (Set_year);
  change_param(c_par);

  while (s_mode != 0) {
    int rDir = rotary.rotate();
    int rBtn = rotary.push();

    //short press on the encoder
    if ( rBtn == 1 )
    {

      if (s_mode == 6) {
        s_mode = 0;

        time.Hours = Set_Hours;
        time.minutes = Set_minutes;
        time.day = Set_day;
        time.month = Set_month;
        time.year = Set_year;
        time.weekday = ned;

        time.settime(0, time.minutes, time.Hours, time.day, time.month, time.year, time.weekday);

        time.gettime("d-m-Y, H:i:s, D");

        dd2 = time.day;
        mm2 = time.month;
        gg2 = time.year;
        hr2 = time.Hours;
        delay(100);
        EEPROM.write(0, Corr_time);
        EEPROM.write(1, dd2);
        EEPROM.write(2, mm2);
        EEPROM.write(3, gg2);
        EEPROM.write(4, hr2);
      }
      else if (s_mode == 5) {
        s_mode = 6;
      }
      else if (s_mode == 4) {
        s_mode = 5;
      }
      else if (s_mode == 3) {
        s_mode = 4;
      }
      else if (s_mode == 2) {
        s_mode = 3;
      }
      else if (s_mode == 1) {
        s_mode = 2;
      }
    }

    if (s_mode == 1) {
      c_par = ("Y:") + String (Set_year);
    }
    else if (s_mode == 2) {
      c_par = "M:" + String (Set_month);
    }
    else if (s_mode == 3) {
      c_par = ("D:") + String (Set_day);
    }
    else if (s_mode == 4) {
      c_par = ("H:") + String (Set_Hours);
    }
    else if (s_mode == 5) {
      c_par = "M:" + String (Set_minutes);
    }
    else if (s_mode == 6) {
      c_par = "K" + String (int(Corr_time));
    }

    change_param(c_par);
    /////////////////////////
    //encoder rotation
    if ( rDir != 0  ) {
      // CW

      if (s_mode == 1) {
        if ( rDir == 1  ) {

          if (Set_year > 50)
          {
            Set_year = 20;
          }
          else
          {
            Set_year ++;
          }

        }

        if ( rDir == 2  ) {

          if (Set_year < 20)
          {
            Set_year = 50;
          }
          else
          {
            Set_year --;
          }

        }
        delay(100);
      }
      else if (s_mode == 2) {
        if ( rDir == 1  ) {

          if (Set_month == 12)
          {
            Set_month = 1;
          }
          else
          {
            Set_month ++;
          }

        }

        if ( rDir == 2  ) {

          if (Set_month == 1)
          {
            Set_month = 12;
          }
          else
          {
            Set_month --;
          }

        }
        delay(100);
      }

      else
        ///////////////////////////////////////WEEKDAY////////////////////////////
        if (s_mode == 3) {
          if (Set_month == 2) {
            LeapYear = 0;  //definition of a leap year
            if ( (((2000 + int(Set_year)) % 4) == 0) & (((2000 + int(Set_year)) % 100) != 0)  || (((2000 + int(Set_year)) % 400) == 0) ) {
              LeapYear = 1;
            }
            else {
              LeapYear = 0;
            }
          }

          if ( rDir == 1  ) {
            if ((Set_day == 31) & (Set_month == 1 || Set_month == 3 || Set_month == 5 || Set_month == 7 || Set_month == 8 || Set_month == 10 || Set_month == 12)) {
              Set_day = 1;
            }
            else if ((Set_day == 30) & (Set_month == 4 || Set_month == 6 || Set_month == 9 || Set_month == 11)) {
              Set_day = 1;
            }
            else if ((Set_day == 29) & (Set_month == 2)) {
              Set_day = 1;
            }
            else if ((Set_day == 28) & (Set_month == 2) & (LeapYear == 0) ) {
              Set_day = 1;
            }

            else
            {
              Set_day ++;
            }

          }

          if ( rDir == 2  ) {

            if (Set_day == 1)
            {
              if ((Set_month == 1 || Set_month == 3 || Set_month == 5 || Set_month == 7 || Set_month == 8 || Set_month == 10 || Set_month == 12)) {
                Set_day = 31;
              }
              else if ((Set_month == 4 || Set_month == 6 || Set_month == 9 || Set_month == 11)) {
                Set_day = 30;
              }
              else if (Set_month == 2) {
                Set_day = 29;
              }
              else if ((Set_month == 2) & (LeapYear == 0) ) {
                Set_day = 28;
              }
            }
            else
            {
              Set_day --;
            }
          }

          //determining the day of the week
          byte a = f_div((14 - int(Set_month)), 12);
          unsigned int y = (2000 + int(Set_year)) - a;
          byte m = int(Set_month) + 12 * a - 2;
          unsigned int y4 = f_div(y, 4);
          byte y100 = f_div(y, 100);
          byte y400 = f_div(y, 400);
          byte x = f_div(31 * m, 12);
          ned = (int(Set_day) + y + y4 - y100 + y400 + x) % 7; //we assign the result to the "net" variable
          delay(100);
        }

      //////////////////////////////////////////////////////
        else if (s_mode == 4) {
          if ( rDir == 1  ) {

            if (Set_Hours == 23)
            {
              Set_Hours = 0;
            }
            else
            {
              Set_Hours ++;
            }

          }

          if ( rDir == 2  ) {

            if (Set_Hours == 0)
            {
              Set_Hours = 23;
            }
            else
            {
              Set_Hours --;
            }

          }
          delay(100);
         }
        else if (s_mode == 5) {
          if ( rDir == 1  ) {

            if (Set_minutes == 59)
            {
              Set_minutes = 0;
            }
            else
            {
              Set_minutes ++;
            }

          }

          if ( rDir == 2  ) {

            if (Set_minutes == 0)
            {
              Set_minutes = 59;
            }
            else
            {
              Set_minutes --;
            }

          }
          delay(100);
        }

        else if (s_mode == 6) {
          if ( rDir == 1  ) {
            if (Corr_time == 59)
            {
              Corr_time = -59;
            }
            else
            {
              Corr_time++;
            }
          }

          if ( rDir == 2  ) {

            if (Corr_time == -59)
            {
              Corr_time = 59;
            }
            else
            {
              Corr_time --;
            }

          }



          delay(100);

        }
    }
    /////////////////////////

  }//end while
}

void light_set ()
{

  //////////////////////////////////////////////setting the brightness
  /*
    //////////////for the green matrix/////////////////
    if (analogRead(lightPin)>=200 & analogRead(lightPin)<=900) ligth_Intensity=(int(analogRead(lightPin)/75));
    if (analogRead(lightPin)<200) ligth_Intensity=0;
    if (analogRead(lightPin)>900) ligth_Intensity=15;

    if (abs(ligth_Intensity2 - ligth_Intensity)>2) {

    ligth_Intensity2=ligth_Intensity;
    matrix.setIntensity(ligth_Intensity);
    }
    //////////////green/////////////////
  */


  //////////////for the red matrix/////////////////
  if (analogRead(lightPin) >= 400 & analogRead(lightPin) <= 1000) ligth_Intensity = (int(analogRead(lightPin) / 100) - 3);


  if (analogRead(lightPin) < 400) ligth_Intensity = 0;
  if (analogRead(lightPin) > 1000) ligth_Intensity = 14;


  if (abs(ligth_Intensity2 - ligth_Intensity) > 2) {

    ligth_Intensity2 = ligth_Intensity;
    matrix.setIntensity(ligth_Intensity);


  }
  //////////////red/////////////////

}